#ifndef LOCALSTACK_
#define LOCALSTACK_

#include <stdlib.h>
#include <stdio.h>

typedef struct LocalStackElem
{
	void* Pointer;
	void (*Destructor) (void*);
	struct LocalStackElem* Next;
	struct LocalStackElem* Back;
} LocalStackElem;

typedef struct GlobalStackElem
{
	char* FunctionName;
	struct GlobalStackElem* Back;
	LocalStackElem* LocalStack;
} GlobalStackElem;

void InitGlobalStack();
void Start(const char* functionName);
void FreeLocalStack();
void DeleteLocalStack();
void ByeBye();
void Safe(void* pointer, void (*destructor) (void*), const char* function, const char* file, int line);
void* New(unsigned size, void (*destructor) (void*), const char* function, const char* file, int line);
void Delete(void* pointer);
void  MDelete(int num, ...);
void End();

void FileCloser(void *file); //helper function to send for file deletion.

#define START()					\
	Start(__FUNCTION__)

#define RETURN(something)	\
{							\
	End();					\
	return something;		\
}

#define SAFED(pointer, destructor)	\
	Safe(pointer, destructor, __FUNCTION__, __FILE__, __LINE__)

#define SAFE(pointer)	\
	Safe(pointer, free, __FUNCTION__, __FILE__, __LINE__)

#define NEWD(size, destructor)	\
	New(size, destructor, __FUNCTION__, __FILE__, __LINE__)

#define NEW(size)	\
	New(size, free, __FUNCTION__, __FILE__, __LINE__)
	
#define Assert(exp)																																\
	if (!(exp))																																	\
	{																																			\
		fprintf(stderr, "Assertation of \"%s\" failed on file \"%s\" in function \"%s\" on line:%d\n", #exp, __FILE__, __FUNCTION__, __LINE__);	\
		ByeBye();																																\
	}

#endif /*LOCALSTACK_*/
